import React, { useRef, useState } from 'react';
import './index.less';
interface DraggableProps {
  style?: React.CSSProperties;
  children: any;
  initPositionX?: number;
  initPositionY?: number;
  disabled?: boolean;
}
function Draggable(props: DraggableProps) {
  let { style, children, initPositionX, initPositionY, disabled } = props;
  if (!initPositionX) {
    initPositionX = 0;
  }
  if (!initPositionY) {
    initPositionY = 0;
  }
  const [position, setPosition] = useState<{ x: number; y: number }>({
    x: initPositionX,
    y: initPositionY,
  });
  const [dragging, setDragging] = useState<boolean>(false);
  const dragRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); //保存元素初始位置
  const requestRef = useRef<number>(0);

  const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
    if (!disabled) {
      setDragging(true);
      dragRef.current = {
        x: event.clientX - event.currentTarget.offsetLeft,
        y: event.clientY - event.currentTarget.offsetTop,
      };
    }
  };

  const handleMouseUp = () => {
    if (!disabled) {
      setDragging(false);
      cancelAnimationFrame(requestRef.current);
    }
  };

  const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {
    if (dragging && !disabled) {
      //使用requestAnimationFrame将更新操作推迟到下一帧渲染时执行,更流畅
      requestRef.current = requestAnimationFrame(() => {
        setPosition({
          x: event.clientX - dragRef.current.x,
          y: event.clientY - dragRef.current.y,
        });
      });
    }
  };

  const positionStyle: React.CSSProperties = {
    left: position.x,
    top: position.y,
  };

  return (
    <div className="draggable-container" style={style}>
      <div
        className="draggable-element"
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onMouseMove={handleMouseMove}
        style={positionStyle}
      >
        {children}
      </div>
    </div>
  );
}
export default Draggable;
